package com.ansion.baseui.base;

import android.os.Bundle;
import android.view.View;

import androidx.annotation.NonNull;

import com.ansion.basetool.observer.BreakNotifyAction;
import com.ansion.basetool.observer.NotifyAction;
import com.ansion.basetool.observer.ObjectManager;

/**
 * @author zhaoyuntao
 * date 2021/6/28
 */
@SuppressWarnings("rawtypes")
public abstract class TVPBaseFragment<P extends TBasePresenter> extends TBaseFragment implements TVPBaseView<P, TVPFragmentUIProxy<? extends TBaseFragment, ? extends P>> {

    private P presenter;
    private final ObjectManager<TVPFragmentUIProxy<? extends TBaseFragment, ? extends P>> manager = new ObjectManager<>(false);

    final public boolean presenterInitFinish() {
        return presenter != null;
    }

    @Override
    final public void initView_base(@NonNull View view, Bundle savedInstanceState) {
        onAddUIProxy();
        initView(savedInstanceState);
        manager.notifyObjects(uiProxy -> {
            uiProxy.initView(savedInstanceState);
        });
    }

    @SuppressWarnings("unchecked")
    @Override
    final public void initData_base(@NonNull View view, Bundle savedInstanceState) {
        presenter = createPresenter();
        presenter.onAttachedView(this);
        initData(savedInstanceState);
        manager.notifyObjects(tvpFragmentUIProxy -> {
            tvpFragmentUIProxy.initData(savedInstanceState);
        });
    }

    protected void onAddUIProxy() {
    }

    @Override
    final public void addUIProxy(TVPFragmentUIProxy<? extends TBaseFragment, ? extends P> uiProxy) {
        manager.addObject(uiProxy);
    }

    final public <UIProxy extends TVPFragmentUIProxy<? extends TBaseFragment, ? extends P>> UIProxy getUIProxy(Class<UIProxy> clazz) {
        UIProxy t = manager.pickObject(clazz);
        if (t == null) {
            throw new RuntimeException("Have you registered this UIProxy[ " + clazz.getSimpleName() + " ]into your activity ?");
        }
        return t;
    }

    @Override
    final public P getPresenter() {
        if (presenter == null) {
            throw new RuntimeException("Please don't use this method in initView()!");
        }
        return presenter;
    }

    @Override
    final public void onClick(View v) {
        if (manager.notifyObjects(uiProxy -> {
            return uiProxy.onClickView(v);
        })) {
            return;
        }
        onClickView(v);
    }

    protected void onClickView(View v) {
    }

    /**
     * When press back key.
     *
     * @return true means consume this click
     */
    @Override
    final public boolean onBackPressed() {
        if (manager.notifyObjects((BreakNotifyAction<TVPFragmentUIProxy<? extends TBaseFragment, ? extends P>>) TVPFragmentUIProxy::onPressedBack)) {
            return true;
        }
        return this.onPressedBack();
    }

    /**
     * When press back key.
     *
     * @return true means consume this click
     */
    protected boolean onPressedBack() {
        return false;
    }

    @Override
    final protected void _onStartFragment() {
        manager.notifyObjects((NotifyAction<TVPFragmentUIProxy<? extends TBaseFragment, ? extends P>>) TVPFragmentUIProxy::onStartFragment);
    }

    @Override
    final protected void _onResumeFragment() {
        manager.notifyObjects((NotifyAction<TVPFragmentUIProxy<? extends TBaseFragment, ? extends P>>) TVPFragmentUIProxy::onResumeFragment);
    }

    @Override
    final protected void _onPauseFragment() {
        manager.notifyObjects((NotifyAction<TVPFragmentUIProxy<? extends TBaseFragment, ? extends P>>) TVPFragmentUIProxy::onPauseFragment);
    }

    @Override
    final protected void _onStopFragment() {
        manager.notifyObjects((NotifyAction<TVPFragmentUIProxy<? extends TBaseFragment, ? extends P>>) TVPFragmentUIProxy::onStopFragment);
    }

    @Override
    final protected void _onDetachFromActivity() {
        manager.notifyObjects((NotifyAction<TVPFragmentUIProxy<? extends TBaseFragment, ? extends P>>) TVPFragmentUIProxy::onDetachFromActivity);
    }

    @Override
    final protected void _onDestroyFragment() {
        manager.notifyObjects((NotifyAction<TVPFragmentUIProxy<? extends TBaseFragment, ? extends P>>) TVPFragmentUIProxy::onDestroyFragment);
        presenter.onDetachedView();
    }
}
